package logic.characters
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.utils.Dictionary; 
	import com.greensock.TweenMax;	
	import flash.events.KeyboardEvent;
	import events.SoundEvent;
	import events.GameEvent;
	import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.filters.BlurFilter;
    import flash.filters.GlowFilter;    
	import flash.geom.Point;
	
	
	public class Player extends Sprite 
	{        
	
	    private const TOP:String = "top";
	    private const BOTTOM:String = "bottom";
	    private const LEFT:String = "left";
	    private const RIGHT:String = "right";
	    
		private var xV:Number = 0;
		private var yV:Number = 0;
		
		private var _landed:Boolean;
		
		public var collisionPoints:Array    
        
        private var keyDict:Dictionary;   
       
		private var explosion:Sprite;
		
		private var falling:Boolean;
		private var jumping:Boolean;
		private var newJump:Boolean = true;;
		private var inertia:Number;
		
		private var lastY:Number;
		private var previosY:Number;
		
		public var dead:Boolean;
		public var levelBottom:Number;
		
		public function Player():void 
		{	          
		    drawMe();
			addEventListener(Event.ADDED_TO_STAGE, init);	
			collisionPoints = [new Point(0, 0), new Point(5, 0), new Point(0, 5), new Point(5, 5)]; 	
			
			
		}
	 	
		private function init(event:Event):void 
		{	
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
			
			keyDict = new Dictionary();	
		}	
		
		private function keyDown(event:KeyboardEvent):void
		{	
            keyDict[event.keyCode] = true;
		}
		
		private function keyUp(event:KeyboardEvent):void
		{
		    keyDict[event.keyCode] = false;	
		    
		    if(event.keyCode == Constants.SPACE)
		        newJump = true;
		    //dispatchEvent(new SoundEvent(SoundEvent.STOP_SOUND, {sound:"move"}, true)); 		    
		}
		
		public function updateLastY(value:Number):void
		{
		    lastY += value;
		}
		
		
		public function update(world:Sprite, enemies:Sprite):void
		{
            

		    var newX:Number = x;
		    var newY:Number = y;
		    
		    if(dead) return;		    
		   	 
	        if (keyDict[Constants.SPACE])
            {               
                if(!falling && newJump)
                {
                    if(jumping == false)
                    {
                        lastY = y; 
                        jumping = true;
                        dispatchEvent(new SoundEvent(SoundEvent.PLAY_SOUND, {sound:"jump"}, true));                          
                    }   
                    
                    newY -= Math.round((y - (lastY - Constants.JUMP_HEIGHT)) * .2)
                    if(y ==  previosY || y <= int(lastY - Constants.JUMP_HEIGHT))
                    {
                        falling = true; 
                        newJump = false
                    }
                    previosY = y;
                     
                    if(checkCollision(world, [new Point(5, 0)]) && checkCollision(world, [new Point(5, 5)]))
                    {
                        newY = y;
                        dispatchEvent(new SoundEvent(SoundEvent.STOP_SOUND, {sound:"jump"}, true));
                    }
                    if(checkCollision(world, [new Point(0, 0)]) && checkCollision(world, [new Point(0, 5)]))
                    {
                        newY = y;
                        dispatchEvent(new SoundEvent(SoundEvent.STOP_SOUND, {sound:"jump"}, true));
                    }
                }
            }   
            else if(jumping)
            {
                jumping = false;  
                falling = true;      
            }        
                       
            if(keyDict[Constants.LEFT])
            {      
                inertia = -Constants.PLAYER_SPEED;               
                if(!checkCollision(world, [new Point(0, 0)]))
                {
                    newX -= Constants.PLAYER_SPEED;                        
                    //dispatchEvent(new SoundEvent(SoundEvent.PLAY_SOUND, {sound:"move", offset:5}, true)); 
                }
            }            
            
            if(keyDict[Constants.RIGHT])
            {    
                inertia = Constants.PLAYER_SPEED;                
                if(!checkCollision(world, [new Point(5, 0)]))
                {  
                    newX += Constants.PLAYER_SPEED;                             
                    //dispatchEvent(new SoundEvent(SoundEvent.PLAY_SOUND, {sound:"move", offset:5}, true)); 
                }
            }    
            
            if(checkCollision(world, [new Point(0, 5), new Point(5, 5)]))
            {
                if(falling)
                   falling = false;
                   
                inertia = 0; 
                   
                jumping = false;
                yV = 0;
                
                if((checkCollision(world, [new Point(0, 0)]) && 
                    checkCollision(world, [new Point(0, 5)]) && 
                    !checkCollision(world, [new Point(5, 5)])) || 
                   (checkCollision(world, [new Point(5, 0)]) && 
                    checkCollision(world, [new Point(5, 5)]) && 
                    !checkCollision(world, [new Point(0, 5)])))
                {
                    newY += Constants.PLAYER_SPEED;
                }
            } 
            else
            {
                if(!jumping)
                    falling = true;
            }
		    
		    if(falling)
		    {      
		        yV += Constants.GRAVITY;
		        newY += yV;

		    }
		    
            if(!keyDict[Constants.LEFT] && !keyDict[Constants.RIGHT] && inertia != 0)
            {
                inertia *= .98
                newX += inertia;  		                   
            }
		   
		    
		    while(y != int(newY))
	        {
	                            
	            if(y > int(newY))
	            {
	                y -= 1;
	            }
	            else
	            {
	                y += 1;
	            }
	            
	                
	            if(checkCollision(world, [new Point(0, 0), new Point(5, 0)]))
	            {
	                 y++;
        	         break;
	            }
	            
	            if(checkCollision(world, collisionPoints))
	               break;
	        }
	        
	        
	        
	        while (x != int(newX))
	        {
	            if(x > int(newX))
	            {
	                x -= 1;
	            }
	            else
	            {
	                x += 1;
	            }
	            
	            if(checkCollision(world, [new Point(0, 0), new Point(5, 0)]))
	                break;
	        }
	        
	        
	        if (y>levelBottom) {
    	        dead = true;
    	        dispatchEvent(new Event("killed"));
    	        dispatchEvent(new SoundEvent(SoundEvent.PLAY_SOUND, {sound:"die"}, true));           
	        }
	        
	        if(checkCollision(enemies, collisionPoints))
	        {
	            if(dead == false)
	            {
	                dead = true;
	                dispatchEvent(new SoundEvent(SoundEvent.PLAY_SOUND, {sound:"die"}, true));           
	                 
	                var particleEm:ParticleEmmiter = new ParticleEmmiter();
                    particleEm.x = 0;
                    particleEm.y = 0;
                    particleEm.xVelocity = 0;
                    particleEm.xSpread = 10;
                    particleEm.yVelocity = -3;
                    particleEm.ySpread = 6;
                    particleEm.beginColor = 0xFF0000;
                    particleEm.endColor = 0xFF0000;
                    particleEm.maxParticles = 250;
                    particleEm.lifetime = 20;
                    particleEm.minGen = 60;
                    particleEm.maxGen = 100;
                    particleEm.start();
                    addChild(particleEm); 			
                    
	                TweenMax.to(this, 2, {alpha:0, onComplete:tweenEnd, onCompleteParams:[particleEm]})
	                
                }        
	        }	        
		}
		
		private function tweenEnd(elem:Sprite):void
		{
		    if(elem && contains(elem))
		        removeChild(elem); 
		    dispatchEvent(new Event("killed"));
		}	
		
		public function drawMe():void 
		{			   
		   graphics.beginFill(0xff00CC, 1)
		   graphics.drawRect(0, 0, 5, 5);
		   graphics.endFill();		   
		}   
		
		private function checkCollision(world:Sprite, points:Array):Boolean
        {
            for(var i:int = 0; i < points.length; i++)
            {
                var point:Point = localToLocal(this, world, points[i]);
                if(world.hitTestPoint(point.x, point.y, true)) 
                    return true;   
            }
            
            return false;		         
        }
        
        private function localToLocal(containerFrom:Sprite, containerTo:Sprite, origin:Point = null):Point
        {
            var point:Point = origin ? origin : new Point();
            point = containerFrom.localToGlobal(point);
            point = containerTo.globalToLocal(point);
            return point;
        } 
		
		
	}	
}
